package luz.javaproxy.gui;


import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.util.regex.Pattern;

import javax.swing.BorderFactory;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.LayoutStyle;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

import luz.javaproxy.common.Tuple;
import luz.javaproxy.config.ConfigMgr;
import luz.javaproxy.plugin.PluginInterface;
import luz.javaproxy.plugin.PluginMgr;
import luz.javaproxy.proxy.Proxy;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;



/**
* This code was edited or generated using CloudGarden's Jigloo
* SWT/Swing GUI Builder, which is free for non-commercial
* use. If Jigloo is being used commercially (ie, by a corporation,
* company or business for any purpose whatever) then you
* should purchase a license for each developer using Jigloo.
* Please visit www.cloudgarden.com for details.
* Use of Jigloo implies acceptance of these licensing terms.
* A COMMERCIAL LICENSE HAS NOT BEEN PURCHASED FOR
* THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED
* LEGALLY FOR ANY CORPORATE OR COMMERCIAL PURPOSE.
*/
public class MainWindow extends javax.swing.JFrame {
	private static final long serialVersionUID = -1781508216824877079L;
	private static final Log log = LogFactory.getLog(MainWindow.class);
	private JTabbedPane tabTabs;
	private JPanel pnlConnection;
	private JButton btnPluginMoveDown;
	private JButton bntPluginMoveUp;
	private JScrollPane scrPlugins;
	private PluginTable tblPlugins;
	private JPanel pnlPlugins;
	private JButton btnStop;
	private JCheckBox chkAutoStart;
	private JButton btnStart;
	private JFormattedTextField txtAddress;
	private JFormattedTextField txtPort;
	private JLabel lblAddress;
	private JLabel lblPort;	
	private JPanel pnlOptions;
	private Proxy proxy;
	private PluginMgr mgr;
	private ConfigMgr cMgr;
	/**
	* Auto-generated main method to display this JFrame
	*/
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				MainWindow inst = new MainWindow(null, null);
				inst.setLocationRelativeTo(null);
				inst.setVisible(true);
			}
		});
	}
	
	public MainWindow(PluginMgr pMgr, ConfigMgr cMgr) {
		super();
		this.mgr=pMgr;
		this.cMgr=cMgr;

		initGUI();

		PluginInterface plugin;
		JPanel pluginPanel;
		for (Tuple<PluginInterface, Boolean> entry : mgr.getPlugins()) {
	    	 plugin = entry.getFirst();
	    	 pluginPanel = plugin.getPluginPanel();
	    	 if (pluginPanel!=null)
	    		 tabTabs.addTab(plugin.getClass().getSimpleName(), null, pluginPanel, null);
		}
 
		if (cMgr.getProxyConfig().getAutoStart()){
			startProxy();
		}	     
	}
	
	private void initGUI() {
		try {
			GroupLayout thisLayout = new GroupLayout((JComponent)getContentPane());
			getContentPane().setLayout(thisLayout);
			setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
			this.setTitle("PluginProxy");
			this.addWindowListener(new WindowAdapter() {
				public void windowClosed(WindowEvent evt) {
					stopProxy();
					cMgr.saveConfig();
					//TODO avoid sys exit
					System.exit(0);
				}
			});
			{
				tabTabs = new JTabbedPane();
				{
					pnlOptions = new JPanel();
					GroupLayout pnlOptionsLayout = new GroupLayout((JComponent)pnlOptions);
					pnlOptions.setLayout(pnlOptionsLayout);
					tabTabs.addTab("Options", null, pnlOptions, null);
					{
						pnlPlugins = new JPanel();
						GroupLayout pnlPluginsLayout = new GroupLayout((JComponent)pnlPlugins);
						pnlPlugins.setLayout(pnlPluginsLayout);
						pnlPlugins.setBorder(BorderFactory.createTitledBorder("Plugins"));
						{
							scrPlugins = new JScrollPane();
							{
								tblPlugins = new PluginTable(mgr);
								scrPlugins.setViewportView(tblPlugins);
							}
						}
						{
							bntPluginMoveUp = new JButton();
							bntPluginMoveUp.setText("MoveUp");
							bntPluginMoveUp.addActionListener(new ActionListener() {
								public void actionPerformed(ActionEvent evt) {
									movePlugin(-1);
								}
							});
						}
						{
							btnPluginMoveDown = new JButton();
							btnPluginMoveDown.setText("MoveDown");
							btnPluginMoveDown.addActionListener(new ActionListener() {
								public void actionPerformed(ActionEvent evt) {
									movePlugin(+1);
								}
							});
						}
						pnlPluginsLayout.setHorizontalGroup(pnlPluginsLayout.createSequentialGroup()
							.addContainerGap()
							.addComponent(scrPlugins, 0, 280, Short.MAX_VALUE)
							.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 10, GroupLayout.PREFERRED_SIZE)
							.addGroup(pnlPluginsLayout.createParallelGroup()
							    .addComponent(bntPluginMoveUp, GroupLayout.Alignment.LEADING, GroupLayout.PREFERRED_SIZE, 90, GroupLayout.PREFERRED_SIZE)
							    .addComponent(btnPluginMoveDown, GroupLayout.Alignment.LEADING, GroupLayout.PREFERRED_SIZE, 90, GroupLayout.PREFERRED_SIZE))
							.addContainerGap());
						pnlPluginsLayout.setVerticalGroup(pnlPluginsLayout.createSequentialGroup()
							.addGroup(pnlPluginsLayout.createParallelGroup()
							    .addGroup(GroupLayout.Alignment.LEADING, pnlPluginsLayout.createSequentialGroup()
							        .addComponent(bntPluginMoveUp, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
							        .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
							        .addComponent(btnPluginMoveDown, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
							        .addGap(0, 112, Short.MAX_VALUE))
							    .addComponent(scrPlugins, GroupLayout.Alignment.LEADING, 0, 164, Short.MAX_VALUE))
							.addContainerGap());
					}
					{
						pnlConnection = new JPanel();
						GroupLayout pnlConnectionLayout = new GroupLayout((JComponent)pnlConnection);
						pnlConnection.setLayout(pnlConnectionLayout);
						pnlConnection.setBorder(BorderFactory.createTitledBorder("Connection"));
						{
							Pattern ipPattern = Pattern.compile("((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])");
							txtAddress = new JFormattedTextField(new RegexPatternFormatter(ipPattern, String.class));
							txtAddress.setValue(cMgr.getProxyConfig().getAddress());
							txtAddress.addPropertyChangeListener("value", new PropertyChangeListener(){
								public void propertyChange( PropertyChangeEvent evt) {
									cMgr.getProxyConfig().setAddress((String)txtAddress.getValue());
								}
							});
						}
						{
							Pattern portPattern = Pattern.compile("(?:6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[0-5]?[0-9]{1,4})");
							txtPort = new JFormattedTextField(new RegexPatternFormatter(portPattern, Integer.class));
							txtPort.setValue(cMgr.getProxyConfig().getPort());
							txtPort.addPropertyChangeListener("value", new PropertyChangeListener(){
								public void propertyChange( PropertyChangeEvent evt) { 
									cMgr.getProxyConfig().setPort((Integer)txtPort.getValue());

								}
							});
						}
						{
							lblAddress = new JLabel();
							lblAddress.setText("Address:");
						}
						{
							lblPort = new JLabel();
							lblPort.setText("Port:");
						}
						{
							btnStart = new JButton();
							btnStart.setText("Start");
							btnStart.addActionListener(new ActionListener() {
								public void actionPerformed(ActionEvent evt) {
									startProxy();
								}
							});
						}
						{
							btnStop = new JButton();
							btnStop.setText("Stop");
							btnStop.setEnabled(false);
							btnStop.addActionListener(new ActionListener() {
								public void actionPerformed(ActionEvent evt) {
									stopProxy();
								}
							});
						}
						{
							chkAutoStart = new JCheckBox();
							chkAutoStart.setText("Auto Start");
							chkAutoStart.setSelected(cMgr.getProxyConfig().getAutoStart());
							chkAutoStart.addActionListener(new ActionListener() {
								public void actionPerformed(ActionEvent evt) {
									cMgr.getProxyConfig().setAutoStart(chkAutoStart.isSelected());
								}
							});
						}
						pnlConnectionLayout.setHorizontalGroup(pnlConnectionLayout.createSequentialGroup()
							.addContainerGap()
							.addGroup(pnlConnectionLayout.createParallelGroup()
							    .addComponent(lblAddress, GroupLayout.Alignment.LEADING, GroupLayout.PREFERRED_SIZE, 60, GroupLayout.PREFERRED_SIZE)
							    .addComponent(lblPort, GroupLayout.Alignment.LEADING, GroupLayout.PREFERRED_SIZE, 60, GroupLayout.PREFERRED_SIZE))
							.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
							.addGroup(pnlConnectionLayout.createParallelGroup()
							    .addComponent(txtAddress, GroupLayout.Alignment.LEADING, GroupLayout.PREFERRED_SIZE, 100, GroupLayout.PREFERRED_SIZE)
							    .addComponent(txtPort, GroupLayout.Alignment.LEADING, GroupLayout.PREFERRED_SIZE, 100, GroupLayout.PREFERRED_SIZE))
							.addGap(0, 189, Short.MAX_VALUE)
							.addGroup(pnlConnectionLayout.createParallelGroup()
							    .addComponent(chkAutoStart, GroupLayout.Alignment.LEADING, GroupLayout.PREFERRED_SIZE, 90, GroupLayout.PREFERRED_SIZE)
							    .addComponent(btnStop, GroupLayout.Alignment.LEADING, GroupLayout.PREFERRED_SIZE, 90, GroupLayout.PREFERRED_SIZE)
							    .addComponent(btnStart, GroupLayout.Alignment.LEADING, GroupLayout.PREFERRED_SIZE, 90, GroupLayout.PREFERRED_SIZE))
							.addContainerGap());
						pnlConnectionLayout.setVerticalGroup(pnlConnectionLayout.createSequentialGroup()
							.addGroup(pnlConnectionLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
							    .addComponent(btnStart, GroupLayout.Alignment.BASELINE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
							    .addComponent(txtAddress, GroupLayout.Alignment.BASELINE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
							    .addComponent(lblAddress, GroupLayout.Alignment.BASELINE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE))
							.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
							.addGroup(pnlConnectionLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
							    .addComponent(btnStop, GroupLayout.Alignment.BASELINE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
							    .addComponent(txtPort, GroupLayout.Alignment.BASELINE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
							    .addComponent(lblPort, GroupLayout.Alignment.BASELINE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE))
							.addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
							.addComponent(chkAutoStart, GroupLayout.PREFERRED_SIZE, 23, GroupLayout.PREFERRED_SIZE)
							.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE));
					}
					pnlOptionsLayout.setHorizontalGroup(pnlOptionsLayout.createSequentialGroup()
						.addContainerGap()
						.addGroup(pnlOptionsLayout.createParallelGroup()
						    .addComponent(pnlPlugins, GroupLayout.Alignment.LEADING, 0, 475, Short.MAX_VALUE)
						    .addComponent(pnlConnection, GroupLayout.Alignment.LEADING, 0, 475, Short.MAX_VALUE))
						.addContainerGap());
					pnlOptionsLayout.setVerticalGroup(pnlOptionsLayout.createSequentialGroup()
						.addContainerGap()
						.addComponent(pnlConnection, GroupLayout.PREFERRED_SIZE, 113, GroupLayout.PREFERRED_SIZE)
						.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
						.addComponent(pnlPlugins, 0, 234, Short.MAX_VALUE)
						.addContainerGap());
				}
			}
			thisLayout.setHorizontalGroup(thisLayout.createSequentialGroup()
				.addComponent(tabTabs, 0, 500, Short.MAX_VALUE));
			thisLayout.setVerticalGroup(thisLayout.createSequentialGroup()
				.addComponent(tabTabs, 0, 400, Short.MAX_VALUE));
			setPreferredSize(new Dimension(500,400));
			setMinimumSize(new Dimension(360,301));
			pack();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void startProxy() {
		//$hide>>$	
    	proxy = new Proxy(
    			cMgr.getProxyConfig().getAddress(), 
    			cMgr.getProxyConfig().getPort(), mgr);

		btnStart.setEnabled(false);
		btnStop.setEnabled(true);
		new Thread(new Runnable(){
			public void run() {
		        try {
		            proxy.run();
		        } catch (InterruptedIOException ex) {
		            log.error("Proxy Interrupted");
		        } catch (IOException e) {
		        	log.error("Proxy I/O error", e);
		        }
		        btnStart.setEnabled(true);
				btnStop.setEnabled(false);
			}
		}, "Proxy-runner").start();
		//$hide<<$
	}
	
	private void stopProxy(){
		//$hide>>$
		if (proxy!=null)
			proxy.shutdown();
		//$hide<<$
	}
	
	private void movePlugin(int diff) {
		//$hide>>$
		PluginInterface plugin= tblPlugins.getSelectedPlugin();
		if (plugin!=null){
			int current = mgr.getPluginPriority(plugin);
			current = mgr.setPluginPriority(plugin, current+diff);
			tblPlugins.updateTable();
			tblPlugins.setSelectedPlugin(current);
		}
		//$hide<<$
	}


	

}
